package com.own.business.push.module.haiwei.client;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.own.business.push.core.base.BasePushClientMethod;
import com.own.business.push.core.model.MessagePushContentModel;
import com.own.business.push.module.haiwei.property.PushHuaweiProperty;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.util.list.ListUtil;
import com.own.component.store.core.Store;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;

/**
 * PushHuaweiClient
 *
 * @author chenxueli
 * @date 2023-11-15 20:37:49
 */
@Slf4j
@Component
public class PushHuaweiClient implements BasePushClientMethod {

    private static final String PUSH_HUAWEI_TOKEN_KEY = "w:c:token:huawei";

    @Resource
    private PushHuaweiProperty pushHuaweiProperty;

    @Resource
    private Store<String> store;

    /**
     * 全量推送
     *
     * @param contentModel 内容
     */
    @Override
    public void all(MessagePushContentModel contentModel) {
    }

    /**
     * 注册id推送
     *
     * @param regIdList    注册id列表
     * @param contentModel 内容
     */
    @Override
    public void regId(List<String> regIdList, MessagePushContentModel contentModel) {
        // 别名推送单词最多1000个
        ListUtil.groupList(regIdList, 800).forEach(values -> {
            var map = buildContent(contentModel, values);
            var request = HttpRequest.post("https://push-api.cloud.huawei.com/v1/" + pushHuaweiProperty.getKey() + "/messages:send").header("Authorization", getAuthorization()).contentType("application/json").body(JSON.toJSONString(map)).execute();
            var body = request.body();
            log.info("华为推送结果:{}", body);
        });
    }

    /**
     * 别名推送信息
     *
     * @param aliasList    别名列表
     * @param contentModel 内容
     */
    @Override
    public void alias(List<String> aliasList, MessagePushContentModel contentModel) {

    }

    /**
     * 构造内容
     *
     * @param contentModel 内容
     * @return 内容
     */
    private JSONObject buildContent(MessagePushContentModel contentModel, List<String> tokenList) {
        var message = new JSONObject();
        message.put("data", JSON.toJSONString(contentModel.getExtras()));
        var notification = new JSONObject();
        notification.put("title", contentModel.getNotificationTitle());
        notification.put("body", contentModel.getContent());
        message.put("notification", notification);
        var android = new JSONObject();
        android.put("title", contentModel.getNotificationTitle());
        android.put("body", contentModel.getContent());
        message.put("android", android);
        message.put("token", tokenList);

        var resultMap = new JSONObject();
        resultMap.put("message", message);
        resultMap.put("validate_only", pushHuaweiProperty.getDev());
        return resultMap;
    }

    /**
     * 获取Authorization
     *
     * @return Authorization
     */
    private String getAuthorization() {
        // 判断是否已经存在token了
        if (store.value().contains(PUSH_HUAWEI_TOKEN_KEY)) {
            return store.value().get(PUSH_HUAWEI_TOKEN_KEY);
        }
        var uri = "https://oauth-login.cloud.huawei.com/oauth2/v3/token?grant_type=client_credentials&client_id=" + pushHuaweiProperty.getKey() + "&client_secret=" + pushHuaweiProperty.getSecret();
        var request = HttpRequest.post(uri).execute();
        var body = request.body();
        if (StringUtils.isBlank(body)) {
            throw new BusinessSimpleException("获取华为推送token失败");
        }
        try {
            var object = JSON.parseObject(body);
            var token = object.getString("access_token");
            var expiresIn = object.getLong("expires_in");
            var tokenType = object.getString("token_type");
            var content = tokenType + " " + token;
            // 存入缓存（expiresIn秒有效）
            store.value().set(PUSH_HUAWEI_TOKEN_KEY, content, Duration.ofSeconds(expiresIn));
            return content;
        } catch (Exception e) {
            throw new BusinessSimpleException("获取华为推送token失败");
        }
    }

    /**
     * 推送发送的名称
     *
     * @return 名称
     */
    @Override
    public String name() {
        return "huawei";
    }

}
